namespace Legend.Threading
{
    using System;
    using System.Threading;

    /// <summary>
    /// An implementation of the ITimer interface for the System.Threading.Timer type.
    /// </summary>
    public class ThreadingTimerAdapter
        : ITimer
    {
        private Timer timer;
        private int interval;
        private static TimerFactory factoryField = x => new ThreadingTimerAdapter(x);

        /// <summary>
        /// Initializes a new instance of the <see cref="ThreadingTimerAdapter"/> class.
        /// </summary>
        /// <param name="interval">The interval.</param>
        public ThreadingTimerAdapter(TimeSpan interval)
        {
            this.interval = (int)interval.TotalMilliseconds;

            this.timer = new System.Threading.Timer(x =>
                {
                    var e = this.Elapsed;
                    if (e != null)
                    {
                        e(this, EventArgs.Empty);
                    }
                }, null, this.interval, this.interval);
        }

        /// <summary>
        /// Occurs a given interval.
        /// </summary>
        public event EventHandler Elapsed;


        /// <summary>
        /// Starts raising the Elapsed-event.
        /// </summary>
        public void Start()
        {
            this.timer.Change(this.interval, this.interval);
        }

        /// <summary>
        /// Stop raising the Elapsed-event.
        /// </summary>
        public void Stop()
        {
            this.timer.Change(Timeout.Infinite, Timeout.Infinite);
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            this.timer.Dispose();
        }

        /// <summary>
        /// Gets a factory for the ThreadingTimerAdapter.
        /// </summary>
        /// <value>The factory.</value>
        public static TimerFactory Factory
        {
            get
            {
                return factoryField;
            }
        }
    }
}
